package org.happy.tester.common.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.happy.tester.common.http.resp.BaseResponse;
import org.happy.tester.common.util.InternetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;

import static org.happy.tester.common.constant.CommonConstant.*;

/**
 * Description
 *
 * @author baijingchuan
 * Date 2020/6/11
 **/
public class CatcherClient extends OkHttpClientUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(CatcherClient.class);

    private String pointcut;

    public boolean needCollect() {
        LOGGER.debug("check【{}】needCollect whether or not", pointcut);
        initOkHttpRequestProvider(CATCHER_ROOT_PATH, COLLECT_NEED, new HashMap<>());
        paramMap.put("pointcut", pointcut);
        String result = doSyncGet();
        BaseResponse<Boolean> response = JSON.parseObject(result, BaseResponse.class);
        boolean needCollect = response.getData();
        LOGGER.debug("pointcut【{}】needCollect return【{}】", pointcut, needCollect);
        return needCollect;
    }

    public void pushCollectResult(Object result) {
        LOGGER.debug("pushCollectResult start,pointcut is【{}】", pointcut);
        String resultJson = JSON.toJSONString(result);
        initOkHttpRequestProvider(CATCHER_ROOT_PATH, COLLECT_RESULT_PUSH, new HashMap<>());
        paramMap.put("pointcut", pointcut);
        paramMap.put("result", resultJson);
        LOGGER.debug("【{}】collect result is 【{}】", pointcut, result);
        doAsyncPostForm();
    }

    public boolean needMock() {
        LOGGER.debug("check【{}】needMock whether or not", pointcut);
        initOkHttpRequestProvider(CATCHER_ROOT_PATH, MOCK_NEED, new HashMap<>());
        paramMap.put("pointcut", pointcut);
        String result = doSyncGet();
        BaseResponse<Boolean> response = JSON.parseObject(result, BaseResponse.class);
        boolean needMock = response.getData();
        LOGGER.debug("pointcut【{}】needMock return【{}】", pointcut, needMock);
        return needMock;
    }

    public Object getMockResult(String resultClassName) {
        LOGGER.debug("get【{}】mock result", pointcut);
        initOkHttpRequestProvider(CATCHER_ROOT_PATH, MOCK_RESULT_GET, new HashMap<>());
        paramMap.put("pointcut", pointcut);
        String result = doSyncGet();
        BaseResponse<JSONObject> response = JSON.parseObject(result, BaseResponse.class);
        Object object = null;
        try {
            object = response.getData().toJavaObject(Class.forName(resultClassName));
        } catch (ClassNotFoundException e) {
            LOGGER.error("result class 【{}】not found", resultClassName);
        }
        LOGGER.debug("【{}】mock result is 【{}】", pointcut, object);
        return object;
    }

    public void markCollect(JSONArray reqParam) {
        LOGGER.debug("mark collect request is【{}】", reqParam);
        initOkHttpRequestProvider(CATCHER_ROOT_PATH, MARK_POINTCUT, new HashMap<>());
        String result = doSyncPostJson(reqParam);
        BaseResponse<Object> response = JSON.parseObject(result, BaseResponse.class);
    }

    public void fixMockResult(JSONArray reqParam) {
        LOGGER.debug("fix mock result request is【{}】", reqParam);
        initOkHttpRequestProvider(CATCHER_ROOT_PATH, MOCK_RESULT_FIX, new HashMap<>());
        String result = doSyncPostJson(reqParam);
        BaseResponse<Object> response = JSON.parseObject(result, BaseResponse.class);
    }

    public String fetchCollectResult(String pointcut) {
        LOGGER.debug("fetch【{}】collect result", pointcut);
        initOkHttpRequestProvider(CATCHER_ROOT_PATH, COLLECT_RESULT_FETCH, new HashMap<>());
        paramMap.put("pointcut", pointcut);
        String result = doSyncGet();
        BaseResponse<String> response = JSON.parseObject(result, BaseResponse.class);
        return response.getData();
    }

    public CatcherClient(String pointcutMiddle) throws IOException {
        concatPointcut(pointcutMiddle);
    }

    public CatcherClient() {
    }

    private void concatPointcut(String pointcutMiddle) throws IOException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String clientIp = "127.0.0.1";
        //这里只处理 nginx 服务代理
        //其他代理参考: https://www.cnblogs.com/sw008/p/11054323.html
        String ipAddresses = request.getHeader("X-Real-IP");
        if (StringUtils.isEmpty(ipAddresses)) {
            clientIp = request.getRemoteAddr();
        } else {
            String ipAddr = ipAddresses.split(",")[0];
            if (ipAddr.split("\\.").length == 4) {
                clientIp = ipAddr;
            }
        }
        pointcut = POINTCUT_JOINER.join(InternetUtils.getOutSideIp(), pointcutMiddle, clientIp);
    }
}
